package com.tanger.im.service.members;

import com.tanger.common.result.ActionResult;
import com.tanger.im.entity.ImUserGroupMembers;
import com.tanger.im.mapper.IMUserGroupMembersRepository;
import com.tanger.im.service.group.IMUserGroupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description TODO
 * @Author Hchenbin
 * @Date 2023-12-25 15:42
 * @Version 1.0
 */
@Slf4j
@Service
public class IMUserGroupMembersServiceImpl implements IMUserGroupMembersService {

    @Autowired
    private IMUserGroupMembersRepository repository;
    @Autowired
    private IMUserGroupService groupService;

    @Override
    public List<ImUserGroupMembers> findAll(Long groupId) {
        return Optional.ofNullable(repository.findAll(
                        Example.of(new ImUserGroupMembers(groupId,null))))
                .orElseGet(Collections::emptyList);
    }

    @Override
    public List<Long> findAllByUserId(Long userId) {
        return Optional.ofNullable(repository.findAll(
                        Example.of(new ImUserGroupMembers(null,userId))))
                .map(ms -> ms.stream()
                        .map(ImUserGroupMembers::getGroupId)
                        .collect(Collectors.toList()))
                .orElseGet(Collections::emptyList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult exit(Long groupId, Long userId) {
        ImUserGroupMembers members = repository.findOne(Example.of(new ImUserGroupMembers(groupId,userId)))
                .orElseThrow(() -> new RuntimeException("群成员信息不存在！"));
        if (members.getIsCreator().intValue() == 1) {
            return ActionResult.buildResultError("请先转让该群后退出，或解散该群");
        }
        repository.deleteById(members.getId());

        groupService.updateMembers(groupId,count(groupId));
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult transfer(Long groupId, Long userId) {
        ImUserGroupMembers members = repository.findOne(Example.of(new ImUserGroupMembers(groupId,userId)))
                .orElseThrow(() -> new RuntimeException("群成员信息不存在！"));
        if (members.getIsCreator().intValue() == 1) {
            return ActionResult.buildResultError("当前成员已为群主");
        }
        members.setIsAdmin(1);
        members.setIsCreator(1);

        ImUserGroupMembers _members = repository.findOne(Example.of(new ImUserGroupMembers(1)))
                .orElseThrow(() -> new RuntimeException("群成员信息不存在！"));
        _members.setIsAdmin(0);
        _members.setIsCreator(0);
        repository.saveAndFlush(_members);

        repository.saveAndFlush(members);
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult delete(Long groupId, List<Long> userIds) {
        List<ImUserGroupMembers> members = findAll(groupId);
        List<Long> ids = members.stream()
                .filter(m -> userIds.stream()
                        .anyMatch(m.getUserId()::equals))
                .map(ImUserGroupMembers::getId)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ids)) {
            repository.deleteAllById(ids);

            groupService.updateMembers(groupId,count(groupId));
        }
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult put(Long groupId, Long userId) {
        ImUserGroupMembers members = repository.findOne(Example.of(new ImUserGroupMembers(groupId,userId)))
                .orElseThrow(() -> new RuntimeException("群成员信息不存在！"));
        if (members.getIsAdmin().intValue() == 1) {
            return ActionResult.buildResultSuccess("OK");
        }
        members.setIsAdmin(1);
        repository.saveAndFlush(members);
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult prohibition(Long groupId, Long userId) {
        ImUserGroupMembers members = repository.findOne(Example.of(new ImUserGroupMembers(groupId,userId)))
                .orElseThrow(() -> new RuntimeException("群成员信息不存在！"));

        if (members.getIsAdmin().intValue() != 1
                && members.getIsCreator().intValue() != 1) {
            return ActionResult.buildResultError("管理员或群主可设置禁言");
        }

        members.setIsProhibition(members.getIsProhibition().intValue() == 1? 0:1);
        repository.saveAndFlush(members);
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult prohibitionAll(Long groupId) {
        List<ImUserGroupMembers> members = findAll(groupId);
        members = members.stream()
                .map(m -> {
                    m.setIsProhibition(m.getIsProhibition().intValue() == 1? 0:1);
                    return m;})
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(members)) {
            repository.saveAllAndFlush(members);
        }
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult save(List<ImUserGroupMembers> members) {
        if (CollectionUtils.isEmpty(members)) {
            return ActionResult.buildResultError("请选择组群成员");
        }
        repository.saveAll(members);
        return ActionResult.buildResultSuccess("OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult deleteByGroupId(Long groupId) {
        List<ImUserGroupMembers> members = findAll(groupId);
        List<Long> ids = members.stream()
                .map(ImUserGroupMembers::getId)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ids)) {
            repository.deleteAllById(ids);
        }
        return ActionResult.buildResultSuccess("OK");
    }

    protected Integer count(Long groupId) {
        Long count = repository.count(Example.of(new ImUserGroupMembers(groupId,null)));
        if (count.longValue() > 0L) {
            return Integer.valueOf(Math.toIntExact(count));
        }
        return 0;
    }
}
